﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Vowei.Data.Models;
using Vowei.Data.Helpers;
using Vowei.Core.Models;
using System.IO;
using Vowei.Data.Converters.Excel;
using Vowei.Data.Converters;
using Vowei.Web.Security;
using Vowei.Core;
using Vowei.Web.Models;
using Vowei.Web.Converters;
using Vowei.Web.Helpers;

namespace Vowei.Web.Controllers
{
    [HandleError]
    [Authorize]
    public class ProjectController : G18nController
    {
        private IVoweiContext _context;
        private IUser _user;

        public ProjectController(IVoweiContext context, IUser user)
        {
            _context = context;
            _user = user;
        }

        [PermissionAuthorize(RequiredPermission = Constants.Permission.Read.Project)]
        public ActionResult Index()
        {
            return View("Index", _context.Projects.Query.GroupBy(p => p.ClosedDate.HasValue).ToArray());
        }

        [PermissionAuthorize(RequiredPermission = Constants.Permission.Read.Project)]
        public ActionResult My()
        {
            return View("Index", _context.Projects.Query.My(_user).GroupBy(p => p.ClosedDate.HasValue).ToArray());
        }

        [PermissionAuthorize(RequiredPermission = Constants.Permission.Read.Project)]
        public ActionResult Timeline(Guid id)
        {
            var project = _context.Projects.Query.SingleOrDefault(p => p.ID == id);
            if (project == null)
                throw new ArgumentException(string.Format(T("找不到ID为{0}的项目!"), id));

            ViewData["Project"] = project;
            return View(new MilestoneProgress[] { MilestoneProgress.CreateFrom(project, _context) });
        }

        public ActionResult ScheduleDetails(Guid id)
        {
            var project = _context.Projects.Find(id);
            if (project == null)
                throw new ArgumentException(string.Format(T("找不到ID为{0}的项目!"), id));

            var converter = new ProjectTimelineConverter(_context);
            ViewData[ViewHelpers.JsonObjectKey] = converter.ConvertFrom(project).ToJson();
            return View(project);
        }

        [PermissionAuthorize(RequiredPermission = Constants.Permission.Read.Project)]
        public ActionResult Progresses()
        {
            var model = new Dictionary<Project, MilestoneProgress>();

            var projects = _context.Projects.Query.My(_user).ToArray();
            foreach (var project in projects)
            {
                model.Add(project, MilestoneProgress.CreateFrom(project, _context));
            }

            return View(model);
        }

        [PermissionAuthorize(RequiredPermission = Constants.Permission.Write.Project)]
        public ActionResult Details(Guid? id)
        {
            if (!id.HasValue)
                throw new ArgumentNullException("id");

            var projects = from p in _context.Projects.Include("Children")
                               // .Include("ResourceAssignments")  // TODO: 当ProjectTeamMemberForeignKeyTest测试通过以后，将这行注释取消掉。 
                                                      .Include("Comments").Query
                           where p.ID == id.Value
                           select p;

            if (projects.Count() == 0)
                throw new ArgumentException(string.Format(T("找不到ID为{0}的项目!"), id.Value));

            var project = projects.First();

            // TODO: update the code once test ProjectTeamMemberForeignKeyTest is fixed
            var pid = project.ID;
            //ViewData["Members"] = 
            //    _context.Assignments.Query.Where(a => a.ProjectId == pid)
            //    .Join(_context.Employees.Query,
            //          a => a.User, e => e.Email, (a, e) => e).ToArray();
            ViewData["Members"] =
                _context.Assignments.Query.Where(a => a.ProjectId == pid)
                .Join(_context.Employees.Query,
                      a => a.ResourceId, e => e.ID, (a, e) => e).ToArray();

            return View(project);
        }

        [PermissionAuthorize(RequiredPermission=Constants.Permission.Write.Project)]
        public ActionResult Create()
        {
            return Edit((Guid?)null);
        }

        // TODO: 删除所有Controller里面的Create Post动作
        // 但是我们需要保留对/<type>/Create之类的支持
        [HttpPost]
        [PermissionAuthorize(RequiredPermission = Constants.Permission.Write.Project)]
        public ActionResult Create(Project project)
        {
            project.OpenDate = DateTime.Now;
            project.Reporter = ViewHelpers.GetLogonUserName();
            return Edit(project);
        }

        [PermissionAuthorize(RequiredPermission = Constants.Permission.Read.Project)]
        public ActionResult Edit(Guid? id)
        {
            return View("Edit", EntityHelpers.GenericGetObjectDetails<Project>(id, _context));
        }

        [HttpPost]
        [PermissionAuthorize(RequiredPermission = Constants.Permission.Write.Project)]
        public ActionResult Edit(Project project)
        {
            var children = project.Children.ToArray();
            project.Children.Clear();
            for (int i = 0; i < children.Length; ++i)
                project.Children.Add((Milestone)_context.Milestones.Find(children.ElementAt(i).ID));

            EditingHelpers.GenericEndEdit(project, _context, _user);

            // TODO: 看看如何把这些小的补丁整合成一个通用的函数
            if (Request != null &&
                Request.AcceptTypes.Any(s => s == "application/json"))
            {
                return WebConstants.HttpSuccess;
            }
            else
            {
                return RedirectToAction("Details", new { id = project.ID });
            }
        }
    }
}
